package org.jeecg.modules.wms.inventory.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.poi.hssf.record.DVALRecord;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.wms.common.constant.CommonWms;
import org.jeecg.modules.wms.inventory.entity.WmsInventory;
import org.jeecg.modules.wms.inventory.mapper.WmsInventoryMapper;
import org.jeecg.modules.wms.inventory.service.IWmsInventoryService;
import org.jeecg.modules.wms.outOrder.entity.WmsOutOrderHeader;
import org.jeecg.modules.wms.stockInChange.entity.WmsStockInChange;
import org.jeecg.modules.wms.stockInChange.mapper.WmsStockInChangeMapper;
import org.jeecg.modules.wms.stockTake.entity.WmsStockTake;
import org.jeecg.modules.wms.stockTake.mapper.WmsStockTakeMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Description: 即时库存
 * @Author: jeecg-boot
 * @Date:   2023-11-13
 * @Version: V1.0
 */
@Service
public class WmsInventoryServiceImpl extends ServiceImpl<WmsInventoryMapper, WmsInventory> implements IWmsInventoryService {

    @Autowired
    private WmsStockInChangeMapper wmsStockInChangeMapper;

    @Autowired
    private WmsStockTakeMapper wmsStockTakeMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void labelAllocation(WmsInventory wmsInventory) {

        //新增标签转移记录
        WmsStockInChange stockInChange = new WmsStockInChange();
        stockInChange.setNewBinCode(wmsInventory.getBinCodeNew());
        stockInChange.setOldBinCode(wmsInventory.getBinCode());
        stockInChange.setNewKwCode(wmsInventory.getKwCode());
        stockInChange.setOldKwCode(wmsInventory.getKwCode());
        stockInChange.setNewTrayCode(wmsInventory.getTrayCode());
        stockInChange.setOldTrayCode(wmsInventory.getTrayCode());
        stockInChange.setShelfOldCount(wmsInventory.getBaseCount());
        stockInChange.setGoodsCode(wmsInventory.getGoodsCode());
        stockInChange.setGoodsName(wmsInventory.getGoodsName());
        this.setStockInChangeNum(stockInChange,"BQZY");
        stockInChange.setSourceId(wmsInventory.getId());
        stockInChange.setRemark(CommonWms.LABEL_ALLOCATION);


        String toBaseCount = Convert.toStr(NumberUtil.sub(wmsInventory.getBaseCount(), wmsInventory.getBaseCountNew()));
        wmsInventory.setBaseCount(toBaseCount);
        this.baseMapper.updateById(wmsInventory);

        stockInChange.setShelfNewCount(toBaseCount);
        wmsStockInChangeMapper.insert(stockInChange);


        //仓库记录  getBinCode   getKwCode  getTrayCode  getGoodsCode
        WmsInventory wmsInventories = this.baseMapper.selectOne(new LambdaQueryWrapper<WmsInventory>()
                        .eq(WmsInventory::getBinCode, wmsInventory.getBinCodeNew())
                        .eq(WmsInventory::getKwCode, wmsInventory.getKwCode())
                        .eq(WmsInventory::getTrayCode, wmsInventory.getTrayCode())
                        .eq(WmsInventory::getCusCode, wmsInventory.getCusCode())
                        .eq(WmsInventory::getGoodsBatch, wmsInventory.getGoodsBatch())
//                .eq(WmsInventory::getGoodsProDate, wmsAuditOutOld.getGoodsProDate())
                        .eq(WmsInventory::getGoodsUnitCode, wmsInventory.getGoodsUnitCode())
                        .eq(WmsInventory::getGoodsCode, wmsInventory.getGoodsCode())
        );

        if (wmsInventories != null) {
            String newCount = Convert.toStr(NumberUtil.add(wmsInventories.getBaseCount(), wmsInventory.getBaseCountNew()));
            wmsInventories.setBaseCount(newCount);
            this.baseMapper.updateById(wmsInventories);
        }else {
            WmsInventory wmsInventoryDto = new WmsInventory();
            BeanUtil.copyProperties(wmsInventory,wmsInventoryDto,"id","create_by","create_time","update_by","update_time");
            wmsInventoryDto.setBaseCount(wmsInventory.getBaseCountNew());
            wmsInventoryDto.setBinCode(wmsInventory.getBinCodeNew());
            this.baseMapper.insert(wmsInventoryDto);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void kwAllocation(WmsInventory wmsInventory) {

        //新增标签转移记录
        WmsStockInChange stockInChange = new WmsStockInChange();
        stockInChange.setNewBinCode(wmsInventory.getBinCode());
        stockInChange.setOldBinCode(wmsInventory.getBinCode());
        stockInChange.setNewKwCode(wmsInventory.getKwCodeNew());
        stockInChange.setOldKwCode(wmsInventory.getKwCode());
        stockInChange.setNewTrayCode(wmsInventory.getTrayCode());
        stockInChange.setOldTrayCode(wmsInventory.getTrayCode());
        stockInChange.setShelfOldCount(wmsInventory.getBaseCount());
        stockInChange.setGoodsCode(wmsInventory.getGoodsCode());
        stockInChange.setGoodsName(wmsInventory.getGoodsName());
        this.setStockInChangeNum(stockInChange,"KWZY");
        stockInChange.setSourceId(wmsInventory.getId());
        stockInChange.setRemark(CommonWms.KW_ALLOCATION);


        String toBaseCount = Convert.toStr(NumberUtil.sub(wmsInventory.getBaseCount(), wmsInventory.getBaseCountNew()));
        wmsInventory.setBaseCount(toBaseCount);
        this.baseMapper.updateById(wmsInventory);

        stockInChange.setShelfNewCount(toBaseCount);
        wmsStockInChangeMapper.insert(stockInChange);


        //仓库记录  getBinCode   getKwCode  getTrayCode  getGoodsCode
        WmsInventory wmsInventories = this.baseMapper.selectOne(new LambdaQueryWrapper<WmsInventory>()
                        .eq(WmsInventory::getBinCode, wmsInventory.getBinCode())
                        .eq(WmsInventory::getKwCode, wmsInventory.getKwCodeNew())
                        .eq(WmsInventory::getTrayCode, wmsInventory.getTrayCode())
                        .eq(WmsInventory::getCusCode, wmsInventory.getCusCode())
                        .eq(WmsInventory::getGoodsBatch, wmsInventory.getGoodsBatch())
//                .eq(WmsInventory::getGoodsProDate, wmsAuditOutOld.getGoodsProDate())
                        .eq(WmsInventory::getGoodsUnitCode, wmsInventory.getGoodsUnitCode())
                        .eq(WmsInventory::getGoodsCode, wmsInventory.getGoodsCode())
        );

        if (wmsInventories != null) {
            String newCount = Convert.toStr(NumberUtil.add(wmsInventories.getBaseCount(), wmsInventory.getBaseCountNew()));
            wmsInventories.setBaseCount(newCount);
            this.baseMapper.updateById(wmsInventories);
        }else {
            WmsInventory wmsInventoryDto = new WmsInventory();
            BeanUtil.copyProperties(wmsInventory,wmsInventoryDto,"id","create_by","create_time","update_by","update_time");
            wmsInventoryDto.setBaseCount(wmsInventory.getBaseCountNew());
            wmsInventoryDto.setKwCode(wmsInventory.getKwCodeNew());
            this.baseMapper.insert(wmsInventoryDto);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void trayAllocation(WmsInventory wmsInventory) {

        //新增标签转移记录
        WmsStockInChange stockInChange = new WmsStockInChange();
        stockInChange.setNewBinCode(wmsInventory.getBinCode());
        stockInChange.setOldBinCode(wmsInventory.getBinCode());
        stockInChange.setNewKwCode(wmsInventory.getKwCode());
        stockInChange.setOldKwCode(wmsInventory.getKwCode());
        stockInChange.setNewTrayCode(wmsInventory.getTrayCodeNew());
        stockInChange.setOldTrayCode(wmsInventory.getTrayCode());
        stockInChange.setShelfOldCount(wmsInventory.getBaseCount());
        stockInChange.setGoodsCode(wmsInventory.getGoodsCode());
        stockInChange.setGoodsName(wmsInventory.getGoodsName());
        this.setStockInChangeNum(stockInChange,"TPZY");
        stockInChange.setSourceId(wmsInventory.getId());
        stockInChange.setRemark(CommonWms.TRAY_ALLOCATION);


        String toBaseCount = Convert.toStr(NumberUtil.sub(wmsInventory.getBaseCount(), wmsInventory.getBaseCountNew()));
        wmsInventory.setBaseCount(toBaseCount);
        this.baseMapper.updateById(wmsInventory);

        stockInChange.setShelfNewCount(toBaseCount);
        wmsStockInChangeMapper.insert(stockInChange);


        //仓库记录  getBinCode   getKwCode  getTrayCode  getGoodsCode
        WmsInventory wmsInventories = this.baseMapper.selectOne(new LambdaQueryWrapper<WmsInventory>()
                        .eq(WmsInventory::getBinCode, wmsInventory.getBinCode())
                        .eq(WmsInventory::getKwCode, wmsInventory.getKwCode())
                        .eq(WmsInventory::getTrayCode, wmsInventory.getTrayCodeNew())
                        .eq(WmsInventory::getCusCode, wmsInventory.getCusCode())
                        .eq(WmsInventory::getGoodsBatch, wmsInventory.getGoodsBatch())
//                .eq(WmsInventory::getGoodsProDate, wmsAuditOutOld.getGoodsProDate())
                        .eq(WmsInventory::getGoodsUnitCode, wmsInventory.getGoodsUnitCode())
                        .eq(WmsInventory::getGoodsCode, wmsInventory.getGoodsCode())
        );

        if (wmsInventories != null) {
            String newCount = Convert.toStr(NumberUtil.add(wmsInventories.getBaseCount(), wmsInventory.getBaseCountNew()));
            wmsInventories.setBaseCount(newCount);
            this.baseMapper.updateById(wmsInventories);
        }else {
            WmsInventory wmsInventoryDto = new WmsInventory();
            BeanUtil.copyProperties(wmsInventory,wmsInventoryDto,"id","create_by","create_time","update_by","update_time");
            wmsInventoryDto.setBaseCount(wmsInventory.getBaseCountNew());
            wmsInventoryDto.setTrayCode(wmsInventory.getTrayCodeNew());
            this.baseMapper.insert(wmsInventoryDto);
        }
    }

    @Override
    public void openlyTake(List<String> asList) {
        List<WmsInventory> wmsInventories = this.baseMapper.selectBatchIds(asList);
        if (CollUtil.isNotEmpty(wmsInventories)){
            WmsStockTake wmsStockTake = new WmsStockTake();
            this.seWmsStockTakeNum(wmsStockTake,"PD");
            for (WmsInventory wmsInventory : wmsInventories) {

                List<WmsStockTake> stockTake = wmsStockTakeMapper.selectList(new LambdaQueryWrapper<WmsStockTake>()
                        .eq(WmsStockTake::getInventoryId,wmsInventory.getId())
                        .eq(WmsStockTake::getTakeStatus,CommonWms.TAKE_STATUS_DPD)
                );
                if (CollUtil.isNotEmpty(stockTake)){
                    List<String> takeId = new ArrayList<>();
                    for (WmsStockTake take : stockTake) {
                        takeId.add(take.getGoodsCode());
                    }
                    throw new JeecgBootException("此物料"+takeId+"已生成盘点单，请核实！");
                }else {
                    wmsStockTake.setId(IdUtil.simpleUUID());
                    wmsStockTake.setBaseCount(wmsInventory.getBaseCount());
                    wmsStockTake.setBinCode(wmsInventory.getBinCode());
                    wmsStockTake.setCusCode(wmsInventory.getCusCode());
                    wmsStockTake.setCusName(wmsInventory.getCusName());
                    wmsStockTake.setGoodsBatch(wmsInventory.getGoodsBatch());
                    wmsStockTake.setGoodsCode(wmsInventory.getGoodsCode());
                    wmsStockTake.setGoodsName(wmsInventory.getGoodsName());
                    wmsStockTake.setGoodsProDate(wmsInventory.getGoodsProDate());
                    wmsStockTake.setGoodsUnitCode(wmsInventory.getGoodsUnitCode());
                    wmsStockTake.setGoodsUnitName(wmsInventory.getGoodsUnitName());
                    wmsStockTake.setTrayCode(wmsInventory.getTrayCode());
                    wmsStockTake.setKwCode(wmsInventory.getKwCode());
//                wmsStockTake.setTakeCyQua(wmsInventory.getBaseCount());
//                wmsStockTake.setTakeQua("0");
                    wmsStockTake.setTakeStatus(CommonWms.TAKE_STATUS_DPD);
                    wmsStockTake.setTakeType(CommonWms.OPENLY_TAKE);
                    wmsStockTake.setInventoryId(wmsInventory.getId());
                    wmsStockTake.setDelFlag(0);
                    wmsStockTakeMapper.insert(wmsStockTake);
                }
            }
        }
    }

    @Override
    public void clouseTake(List<String> asList) {
        List<WmsInventory> wmsInventories = this.baseMapper.selectBatchIds(asList);
        if (CollUtil.isNotEmpty(wmsInventories)){
            WmsStockTake wmsStockTake = new WmsStockTake();
            this.seWmsStockTakeNum(wmsStockTake,"PD");
            for (WmsInventory wmsInventory : wmsInventories) {

                List<WmsStockTake> stockTake = wmsStockTakeMapper.selectList(new LambdaQueryWrapper<WmsStockTake>()
                        .eq(WmsStockTake::getInventoryId,wmsInventory.getId())
                        .eq(WmsStockTake::getTakeStatus,CommonWms.TAKE_STATUS_DPD)
                );
                if (CollUtil.isNotEmpty(stockTake)){
                    List<String> takeId = new ArrayList<>();
                    for (WmsStockTake take : stockTake) {
                        takeId.add(take.getGoodsCode());
                    }
                    throw new JeecgBootException("此物料"+takeId+"已生成盘点单，请核实！");
                }else {
                    wmsStockTake.setId(IdUtil.simpleUUID());
//                wmsStockTake.setBaseCount(wmsInventory.getBaseCount());
                    wmsStockTake.setBinCode(wmsInventory.getBinCode());
                    wmsStockTake.setCusCode(wmsInventory.getCusCode());
                    wmsStockTake.setCusName(wmsInventory.getCusName());
                    wmsStockTake.setGoodsBatch(wmsInventory.getGoodsBatch());
                    wmsStockTake.setGoodsCode(wmsInventory.getGoodsCode());
                    wmsStockTake.setGoodsName(wmsInventory.getGoodsName());
                    wmsStockTake.setGoodsProDate(wmsInventory.getGoodsProDate());
                    wmsStockTake.setGoodsUnitCode(wmsInventory.getGoodsUnitCode());
                    wmsStockTake.setGoodsUnitName(wmsInventory.getGoodsUnitName());
                    wmsStockTake.setTrayCode(wmsInventory.getTrayCode());
                    wmsStockTake.setKwCode(wmsInventory.getKwCode());
//                wmsStockTake.setTakeCyQua(wmsInventory.getBaseCount());
//                wmsStockTake.setTakeQua("0");
                    wmsStockTake.setTakeStatus(CommonWms.TAKE_STATUS_DPD);
                    wmsStockTake.setTakeType(CommonWms.CLOUSE_TAKE);
                    wmsStockTake.setDelFlag(0);
                    wmsStockTake.setInventoryId(wmsInventory.getId());
                    wmsStockTakeMapper.insert(wmsStockTake);
                }
            }
        }
    }

    private void setStockInChangeNum(WmsStockInChange stockInChange,String orderNum) {
        //生成订单号
        Long aLong = wmsStockInChangeMapper.selectCount(new LambdaQueryWrapper<WmsStockInChange>()
                .like(WmsStockInChange::getOrderNum,orderNum)
                .apply("date_format(create_time,'%Y-%m-%d') = '" + DateUtil.today() + "'"));
        int count = Math.toIntExact(aLong);
        stockInChange.setOrderNum(orderNum
                + DateUtils.date2Str(new SimpleDateFormat("yyyyMMdd"))
                + "-"
                + String.format("%04d", (count + 1)));
    }

    private void seWmsStockTakeNum(WmsStockTake wmsStockTake,String orderNum) {
        List<WmsStockTake> stockTake = wmsStockTakeMapper.selectList(new LambdaQueryWrapper<WmsStockTake>()
                .apply("date_format(create_time,'%Y-%m-%d') = '" + DateUtil.today() + "'")
                .orderByDesc(WmsStockTake::getTakeNum)
        );
        if (CollUtil.isNotEmpty(stockTake)){
            WmsStockTake take = stockTake.get(0);
            String takeNum = take.getTakeNum();
            String[] split = takeNum.split("-");
            Integer integer = Convert.toInt(split[1]) + 1;
            wmsStockTake.setTakeNum(split[0]+"-"+String.format("%04d", (integer)));
        }else {
            //生成订单号
            Long aLong = wmsStockTakeMapper.selectCount(new LambdaQueryWrapper<WmsStockTake>()
                    .like(WmsStockTake::getTakeNum,orderNum)
                    .apply("date_format(create_time,'%Y-%m-%d') = '" + DateUtil.today() + "'")
            );
            int count = Math.toIntExact(aLong);
            wmsStockTake.setTakeNum(orderNum
                    + DateUtils.date2Str(new SimpleDateFormat("yyyyMMdd"))
                    + "-"
                    + String.format("%04d", (count+1)));
        }
    }
}
